import {
  BodyAttrs,
  EVENT_EMITTER_NAMES,
  getCurrentURL,
  logger,
  loggerDeduplicator,
} from '../types/constants'
import { EventEmitter } from './event_emitter'
import { ToolKit } from './utils/toolkit'

export class UrlHandler {
  readonly id: string = 'url-handler'
  readonly name: string = 'UrlHandler'
  private static instance: UrlHandler
  private readonly eventEmitter: EventEmitter = EventEmitter.getInstance()
  private lastUrl: string | null = null
  private resolvedUrl: string = ''
  private navigationResolved: boolean = false

  constructor() {
    this.setupUrlObserver()
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): UrlHandler {
    if (!UrlHandler.instance) {
      UrlHandler.instance = new UrlHandler()
    }
    return UrlHandler.instance
  }

  /**
   * 初始化 URL 跟踪系统
   */
  startTracking(): void {
    try {
      this.getFinalUrl().then((url) => {
        $(document.body).data(BodyAttrs.FINAL_URL, url)

        if (this.lastUrl && this.lastUrl !== url) {
          this.eventEmitter.emit(EVENT_EMITTER_NAMES.urlChanged)

          logger.info(`[${this.name}] URL 已更新`, {
            lastUrl: this.lastUrl,
            currentUrl: url,
          })
        }
        else {
          loggerDeduplicator.highlight(`[${this.name}] 网页 URL 识别处理完成`, url)
        }

        this.lastUrl = url
      })
    }
    catch (error: any) {
      logger.error(`[${this.name}] URL 保存失败: ${error.message}`)
    }
  }

  /**
   * 处理 URL 变化
   */
  private handleUrlChange = (): void => {
    this.navigationResolved = false
    this.startTracking()
  }

  /**
   * 初始化 URL 属性观察器
   */
  private setupUrlObserver(): void {
    if (window.onurlchange === null) {
      window.addEventListener('urlchange', (_info) => {
        this.handleUrlChange()
      })
    }
  }

  /**
   * 等待导航稳定
   */
  private async waitForNavigationStable(): Promise<void> {
    return new Promise((resolve) => {
      const checkStable = () => {
        const currentUrl = this.getRawUrl()
        setTimeout(() => {
          if (currentUrl === this.getRawUrl()) {
            this.resolvedUrl = currentUrl
            this.navigationResolved = true
            resolve()
          }
          else {
            checkStable()
          }
        }, 150) // 150ms内无变化视为稳定
      }

      if (document.readyState === 'complete') {
        checkStable()
      }
      else {
        window.addEventListener('load', () => checkStable(), { once: true })
      }
    })
  }

  /**
   * 获取原始 URL（不处理重定向）
   */
  private getRawUrl(): string {
    let url = ''

    try {
      if (ToolKit.browser.platform.isIframe() && window.top) {
        return window.top.location.href
      }
      else {
        return getCurrentURL()
      }
    }
    catch (e) {
      url = getCurrentURL()
      logger.warn(`跨域限制，使用当前窗口 URL（${url}）`, e)
    }

    return url
  }

  /**
   * 获取最终稳定URL
   */
  async getFinalUrl(): Promise<string> {
    if (this.navigationResolved) {
      return this.resolvedUrl
    }

    // 双重验证机制
    const url1 = this.getRawUrl()
    await new Promise(resolve => setTimeout(resolve, 50))
    const url2 = this.getRawUrl()

    if (url1 === url2) {
      this.resolvedUrl = url2
      this.navigationResolved = true

      return url2
    }

    // URL 仍在变化，重新等待稳定
    await this.waitForNavigationStable()
    return this.resolvedUrl
  }
}
